package com.nidu.demo.redis.config;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.nio.charset.StandardCharsets;

/**
 * Redis自动配置类
 * 用于非缓存的Redis操作，如分布式锁、数据存储等
 *
 * @author nidu
 */
@Slf4j
@Configuration
@ConditionalOnClass(RedisTemplate.class)
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {

    /**
     * 创建 RedisTemplate Bean，使用 JSON 序列化方式
     * 用于存储复杂对象数据
     */
    @Bean("redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        log.info("[RedisAutoConfiguration][初始化 RedisTemplate]");
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        // 设置序列化器
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        template.setValueSerializer(buildRedisSerializer());
        template.setHashValueSerializer(buildRedisSerializer());
        
        // 启用事务支持
        template.setEnableTransactionSupport(true);
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 创建 StringRedisTemplate Bean
     * 用于简单的字符串操作和分布式锁
     */
    @Bean("stringRedisTemplate")
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        log.info("[RedisAutoConfiguration][初始化 StringRedisTemplate]");
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(factory);
        return template;
    }

    /**
     * 构建 Redis 序列化器，使用 FastJSON2
     */
    private RedisSerializer<Object> buildRedisSerializer() {
        return new RedisSerializer<Object>() {
            @Override
            public byte[] serialize(Object object) {
                if (object == null) {
                    return new byte[0];
                }
                return JSON.toJSONBytes(object, 
                    JSONWriter.Feature.WriteClassName,
                    JSONWriter.Feature.WriteEnumUsingToString,
                    JSONWriter.Feature.WriteNulls,
                    JSONWriter.Feature.NotWriteRootClassName);
            }

            @Override
            public Object deserialize(byte[] bytes) {
                if (bytes == null || bytes.length == 0) {
                    return null;
                }
                String str = new String(bytes, StandardCharsets.UTF_8);
                return JSON.parseObject(str, Object.class, 
                    JSONReader.Feature.UseNativeObject);
            }
        };
    }
}
